package model

import (
	"errors"
	"jiance_server/log"
	"jiance_server/mongo"

	mgo "gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

type Class struct {
	ID         string   `bson:"_id,omitempty" json:"id"`
	Title      string   `bson:"Title,omitempty" json:"title"`
	Link       string   `bson:",omitempty" json:"link"`
	CreateTime int64    `bson:"CreateTime,omitempty" json:"createTime"`
	Num        int64    `bson:"Num,omitempty" json:",omitempty"`
	Max        int64    `bson:"Max,omitempty" json:",omitempty"`
	Type       string   `bson:"Type,omitempty" json:",omitempty"`
	Teacher    string   `bson:"Teacher,omitempty" json:",omitempty"`
	UserIDs    []string `bson:"UserIDs,omitempty" json:",omitempty"`
}

func (class *Class) SubscribedBy(userID string) error {
	err := mongo.Class.WithC(func(c *mgo.Collection) error {
		return c.Update(bson.M{
			"_id": class.ID,
			"Num": bson.M{"$lt": class.Max}, // 保证写入数据库时还是Num<Max
		}, bson.M{
			"$set":      bson.M{"Num": class.Num + 1},
			"$addToSet": bson.M{"UserIDs": userID},
		})
	})
	if err != nil {
		log.Errorln(err)
		return errors.New("预约失败!")
	}
	err = mongo.Users.WithC(func(c *mgo.Collection) error {
		return c.UpdateId(userID, bson.M{
			"$addToSet": bson.M{"ClassIDs": class.ID},
		})
	})
	if err != nil {
		log.Errorln("update class success,but update user error:", err)
		return errors.New("预约失败!")
	}
	return err
}

func (class *Class) SetLink(prefix string) {
	class.Link = prefix + class.ID
}

func FindClassByID(id string, selector interface{}) (class *Class, err error) {
	class = &Class{}
	err = mongo.Class.WithC(func(c *mgo.Collection) error {
		return c.FindId(id).Select(selector).One(class)
	})
	return class, err
}

func FindClassByIDs(ids []string, pageIndex int, pageSize int, selector interface{}) (classes []Class, err error) {
	return classes, mongo.Class.WithC(func(c *mgo.Collection) error {
		return c.Find(bson.M{"_id": bson.M{"$in": ids}}).Select(selector).Skip(pageIndex * pageSize).Limit(pageSize).All(&classes)
	})
}

func ListClass(pageIndex int, pageSize int, selector interface{}) (classes []Class, err error) {
	return classes, mongo.Class.WithC(func(c *mgo.Collection) error {
		return c.Find(nil).Select(selector).Skip(pageIndex * pageSize).Limit(pageSize).All(&classes)
	})
}
